<?php

namespace app\api\model;

use app\common\model\Reservation;
use think\Cache;
use app\common\library\wechat\WxUser;
use app\common\exception\BaseException;
use app\common\model\User as UserModel;
use app\api\model\dealer\Referee as RefereeModel;
use app\api\model\dealer\Setting as DealerSettingModel;

/**
 * 用户模型类
 * Class User
 * @package app\api\model
 */
class User extends UserModel
{
    private $token;

    /**
     * 隐藏字段
     * @var array
     */
    protected $hidden = [
        'open_id',
        'is_delete',
        'wxapp_id',
        'create_time',
        'update_time'
    ];

    /**
     * 获取用户信息
     * @param $token
     * @return null|static
     * @throws \think\exception\DbException
     */
    public static function getUser($token)
    {
        $openId = Cache::get($token)['openid'];
        return self::detail(['open_id' => $openId], ['address', 'addressDefault', 'grade']);
    }

    public function test($post){
        $session = $this->wxlogin($post['code']);
        dump($session);
    }

    /**
     * 用户登录
     * @param array $post
     * @return string
     * @throws BaseException
     * @throws \think\Exception
     * @throws \think\exception\DbException
     */
    public function login($post)
    {
        // 微信登录 获取session_key
        $session = $this->wxlogin($post['code']);
        // 自动注册用户
        $refereeId = isset($post['referee_id']) ? $post['referee_id'] : null;
        $userInfo = json_decode(htmlspecialchars_decode($post['user_info']), true);
//        $actualInfo = $this->getUserInfo($post['encrypted_data'],$post['iv'],$session['session_key']);
//        $info = json_decode($actualInfo,true);
        $user_id = $this->register($session['openid'], $userInfo,isset($session['unionid'])?$session['unionid']:'', $refereeId);
        // 生成token (session3rd)
        $this->token = $this->token($session['openid']);
        // 记录缓存, 7天
        Cache::set($this->token, $session, 86400 * 7);
        return $user_id;
    }

    public function getUserInfo($encryptedData,$iv,$session_key){
        include_once "wxBizDataCrypt.php";
        $wxConfig = Wxapp::getWxappCache();
        if (empty($wxConfig['app_id']) || empty($wxConfig['app_secret'])) {
            throw new BaseException(['msg' => '请到 [后台-小程序设置] 填写appid 和 appsecret']);
        }
        $pc = new \WXBizDataCrypt($wxConfig['app_id'], $session_key);
        $errCode = $pc->decryptData($encryptedData, $iv, $data );
        if ($errCode == 0) {
            return $data;
        } else {
            throw new BaseException(['msg' => '授权失败']);
        }
    }

    public function getPhone($post){
        // 微信登录 获取session_key
        $wxConfig = Wxapp::getWxappCache();
        // 验证appid和appsecret是否填写
        if (empty($wxConfig['app_id']) || empty($wxConfig['app_secret'])) {
            throw new BaseException(['msg' => '请到 [后台-小程序设置] 填写appid 和 appsecret']);
        }
        // 微信登录 (获取session_key)
        $WxUser = new WxUser($wxConfig['app_id'], $wxConfig['app_secret']);
        $accesstoken = $WxUser->accessToken();
        if (!$phone_res = $WxUser->getPhoneNumber($accesstoken,$post['code'])) {
            throw new BaseException(['msg' => $WxUser->getError()]);
        }
        return $phone_res;
    }

    /**
     * 获取token
     * @return mixed
     */
    public function getToken()
    {
        return $this->token;
    }

    /**
     * 微信登录
     * @param $code
     * @return array|mixed
     * @throws BaseException
     * @throws \think\exception\DbException
     */
    private function wxlogin($code)
    {
        // 获取当前小程序信息
        $wxConfig = Wxapp::getWxappCache();
        // 验证appid和appsecret是否填写
        if (empty($wxConfig['app_id']) || empty($wxConfig['app_secret'])) {
            throw new BaseException(['msg' => '请到 [后台-小程序设置] 填写appid 和 appsecret']);
        }
        // 微信登录 (获取session_key)
        $WxUser = new WxUser($wxConfig['app_id'], $wxConfig['app_secret']);
        if (!$session = $WxUser->sessionKey($code)) {
            throw new BaseException(['msg' => $WxUser->getError()]);
        }
        return $session;
    }

    /**
     * 生成用户认证的token
     * @param $openid
     * @return string
     */
    private function token($openid)
    {
        $wxapp_id = self::$wxapp_id;
        // 生成一个不会重复的随机字符串
        $guid = \getGuidV4();
        // 当前时间戳 (精确到毫秒)
        $timeStamp = microtime(true);
        // 自定义一个盐
        $salt = 'token_salt';
        return md5("{$wxapp_id}_{$timeStamp}_{$openid}_{$guid}_{$salt}");
    }

    /**
     * 自动注册用户
     * @param $open_id
     * @param $unionid
     * @param $data
     * @param int $refereeId
     * @return mixed
     * @throws \Exception
     * @throws \think\exception\DbException
     */
    private function register($open_id, $data,$unionid='', $refereeId = null)
    {
        // 查询用户是否已存在
        $user = self::detail(['open_id' => $open_id]);
//        $model = $user ?: $this;
        $model = $user ?: $this;
        $this->startTrans();
        try {
            if (!$user){
                // 保存/更新用户记录
                if (!$model->allowField(true)->save(array_merge($data, [
                    'open_id' => $open_id,
                    'unionid' => $unionid,
                    'wxapp_id' => self::$wxapp_id
                ]))) {
                    throw new BaseException(['msg' => '用户注册失败']);
                }
            }elseif ($user['unionid'] == ''){
                if (!$model->allowField(true)->save([
                    'unionid' => $unionid,
                ])) {
                    throw new BaseException(['msg' => '用户登录失败']);
                }
            }

            // 记录推荐人关系
            if (!$user && $refereeId > 0) {
                RefereeModel::createRelation($model['user_id'], $refereeId);
            }
            $this->commit();
        } catch (\Exception $e) {
            $this->rollback();
            throw new BaseException(['msg' => $e->getMessage()]);
        }
        return $model['user_id'];
    }

    /**
     * 个人中心菜单列表
     * @return array
     */
    public function getMenus()
    {
        $menus = [
//            'sign' => [
//                'name' => '积分签到',
//                'url' => 'pages/sign/index',
//                'icon' => 'z-new'
//            ],
            'video' => [
                'name' => '视频课程',
                'url' => 'pages/user/video/index',
                'icon' => 'z-new'
            ],
            'card' => [
                'name' => '我的课程卡',
                'url' => 'pages/user/boxing/cardlist',
                'icon' => 'z-new'
            ],
            'lesson' => [
                'name' => '我的课程',
                'url' => 'pages/user/boxing/lesson',
                'icon' => 'templatedefault'
            ],
            'appoint' => [
                'name' => '我的预约',
                'url' => 'pages/user/train/index',
                'icon' => 'shehuituanti'
            ],
            'user' => [
                'name' => '我的会员',
                'url' => 'pages/user/myvip/index',
                'icon' => 'shehuituanti'
            ],
            'homework' => [
                'name' => '课后作业',
                'url' => 'pages/user/train/homework',
                'icon' => 'daohang'
            ],
            'health' => [
                'name' => '健康数据',
                'url' => 'pages/user/health/health',
                'icon' => 'miaosha-b'
            ],
            'address' => [
                'name' => '收货地址',
                'url' => 'pages/address/index',
                'icon' => 'map'
            ],
//            'coupon' => [
//                'name' => '领券中心',
//                'url' => 'pages/coupon/coupon',
//                'icon' => 'lingquan'
//            ],
            'my_coupon' => [
                'name' => '我的优惠券',
                'url' => 'pages/user/coupon/coupon',
                'icon' => 'youhuiquan'
            ],
            'sharing_order' => [
                'name' => '拼团订单',
                'url' => 'pages/sharing/order/index',
                'icon' => 'pintuan'
            ],
            'my_bargain' => [
                'name' => '我的砍价',
                'url' => 'pages/bargain/index/index?tab=1',
                'icon' => 'kanjia'
            ],
            'dealer' => [
                'name' => '分销中心',
                'url' => 'pages/dealer/index/index',
                'icon' => 'fenxiaozhongxin'
            ],
            'help' => [
                'name' => '我的帮助',
                'url' => 'pages/user/help/index',
                'icon' => 'help'
            ],
        ];
        // 判断分销功能是否开启
        if (DealerSettingModel::isOpen()) {
            $menus['dealer']['name'] = DealerSettingModel::getDealerTitle();
        } else {
            unset($menus['dealer']);
        }
        return $menus;
    }

    public function userDetail($user_id){
//        $info = $this->where('user_id','=',$user_id)->with(['reservation'=>function($query){
//            $query->where(['status'=>['in',[0,1,2]]])->order('id desc');
//        },'reservation.orderdetail','card'=>function($q_card){
//            $q_card->whereIn('card_status','1,2')->where('is_active','=',1);
//        }])->withCount('card')->find();
        $info = $this->where('user_id','=',$user_id)->with(['card'=>function($q_card){
            $q_card->whereIn('card_status','1,2,3')->where('is_active','=',1)->with(['file','reservation'=>function($reser){
                $reser->order('id desc')->field('work_status,work_title,work_content',true);
            }]);
        }])->withCount('card')->find();
        $info = $info->toArray();
        if (preg_match('/(uploads)/',$info['avatarUrl'])){
            $info['avatarUrl'] = base_url().$info['avatarUrl'];
        }
//        if (count($info['reservation']) > 0){
//            $first = $info['reservation'][0];
//            unset($info['reservation']);
//            $info['reservation'] = $first;
//        }
//        if ($info['reservation']['orderdetail']['start_time']){
//            $info['reservation']['orderdetail']['start_time'] = date('Y-m-d',$info['reservation']['orderdetail']['start_time']);
//        }
//        if ($info['reservation']['orderdetail']['expire_time']){
//            $info['reservation']['orderdetail']['expire_time'] = date('Y-m-d',$info['reservation']['orderdetail']['expire_time']);
//        }
        foreach ($info['card'] as $kk=>$vv){
            if (in_array($vv['card_status'],[1,2])){
                $info['card'][$kk]['is_available'] = true;
            }else{
                //不可用
                $info['card'][$kk]['is_available'] = false;
            }
            $info['card'][$kk]['start_time'] = date('Y-m-d',$vv['start_time']);
            $info['card'][$kk]['expire_time'] = date('Y-m-d',$vv['expire_time']);
            if ($vv['reservation']){
                $info['card'][$kk]['last_reservation'] = $vv['reservation'][0];
            }else{
                $info['card'][$kk]['last_reservation'] = '';
            }
            unset($info['card'][$kk]['reservation']);
        }
        $info['show_card'] =  $info['card'][0];
        return $info;
    }

    public function getList($param,$coach_id=11){
        $params = array_merge([
            'name'=>'',
            'page'=>1
        ],$param);

//        $list = $this->withCount(['card'=>function($query){
//            $query->where(['is_active'=>1,'card_status'=>['in',[1,2]]]);
//        }])->field('*')->having('card_count>0')->paginate(13);
//        dump($list->toArray());die;
        $cardModel = new CourseOrderDetail();
        $reservationModel = new Reservation();
        $reservation_user_ids = [];
        if ($params['name'] == ''){
            $reservation_user_ids = $reservationModel->where(['coach_id'=>$coach_id])->column('user_id');
        }else{
//            $reservation_user_ids = self::where('nickName|phone','like',"%{$params['name']}%")->column('user_id');
            $reservation_user_ids = self::where('nickName','like',"%{$params['name']}%")->column('user_id');
        }
        $user_ids = $cardModel->where(['is_active'=>1,'card_status'=>['in',[1,2,3]]])->whereIn('user_id',$reservation_user_ids)->group('user_id')->column('user_id');

//        $list = $this->whereIn('user_id',$user_ids)->with(['reservation'=>function($query){
//            $query->with('orderdetail')->where(['status'=>['in',[0,1,2]]])->order('id desc');
//        },'card'=>function($q_card){
//            $q_card->whereIn('card_status','1,2')->where('is_active','=',1)->with(['file','reservation'=>function($reser){
//                $reser->order('id desc');
//            }]);
//        }])->withCount('card')->paginate(13);
        $list = $this
            ->where('is_delete','=',0)->whereIn('user_id',$user_ids)->with(['card'=>function($q_card){
            $q_card->whereIn('card_status','1,2,3')->where('is_active','=',1)->where('is_delete','=',0)->with(['file','reservation'=>function($reser){
                $reser->order('id desc')->field('work_status,work_title,work_content',true);
            }]);
        }])->withCount('card')->paginate(13);
        $list = $list->toArray();
        $list = $this->buildData($list);
        return $list;
//        dump($list);die;
    }

    protected function buildData($list){
        foreach ($list['data'] as $k=>&$v){
            if (preg_match('/(uploads)/',$v['avatarUrl'])){
                $v['avatarUrl'] = base_url().$v['avatarUrl'];
            }
//            if ($v['reservation']){
//                $v['reservation'] = $v['reservation'][0];
//            }
//            if ($v['reservation']['orderdetail']['start_time']){
//                $v['reservation']['orderdetail']['start_time'] = date('Y-m-d',$v['reservation']['orderdetail']['start_time']);
//            }
//            if ($v['reservation']['orderdetail']['expire_time']){
//                $v['reservation']['orderdetail']['expire_time'] = date('Y-m-d',$v['reservation']['orderdetail']['expire_time']);
//            }
            //2023 05 15 取出第一张卡
            //2023 07 05 22:00  用户没有卡的情况
            if ($v['card']){
                foreach ($v['card'] as $kk=>$vv){
                    if (in_array($vv['card_status'],[1,2])){
                        $v['card'][$kk]['is_available'] = true;
                    }else{
                        //不可用
                        $v['card'][$kk]['is_available'] = false;
                    }
                    $v['card'][$kk]['start_time'] = date('Y-m-d',$vv['start_time']);
                    $v['card'][$kk]['expire_time'] = date('Y-m-d',$vv['expire_time']);
                    if ($vv['reservation']){
                        $list['data'][$k]['card'][$kk]['last_reservation'] = $vv['reservation'][0];
                    }else{
                        $list['data'][$k]['card'][$kk]['last_reservation'] = '';
                    }

                    unset($v['card'][$kk]['reservation']);
                }
                $list['data'][$k]['show_card'] =  $list['data'][$k]['card'][0];
            }else{
                //没有卡的情况
                $list['data'][$k]['show_card'] =  [];
            }

//            $show_card = $v['card'][0];
//            $v['show_card'] = $show_card;
//            $v['show_card']['last_reservation'] = $v['show_card']['reservation'][0];
        }
        return $list;
    }

}
